Typical HAL ICACHE use cases for migration

This section provides information about typical HAL ICACHE use cases for migration.

Use case: ICACHE maintenance operations in polling mode

This use case shows how to configure ICACHE and run maintenance operations (invalidate) in polling mode.

Sequence diagram

    @startuml

    skinparam sequenceMessageAlign center

    participant "User\nApplication" as UA
    participant "ICACHE\nDriver" as ID

    group Loop [Can be repeated]

    group Optional
    UA->ID : **HAL_ICACHE_ConfigAssociativityMode**
    ID --> UA : return HAL_OK
    UA->ID : **HAL_ICACHE_Monitor_Start**
    ID --> UA : return HAL_OK
    |||
    end
    UA->ID : **HAL_ICACHE_Enable**
    ID --> UA : return HAL_OK

    group Loop [Can be repeated]
    UA->ID : **HAL_ICACHE_Invalidate**
    ID --> UA : return HAL_OK, HAL_BUSY, HAL_ERROR, HAL_TIMEOUT
    |||
    end
    group Optional
    UA->ID : **HAL_ICACHE_Monitor_GetHitValue**, **HAL_ICACHE_Monitor_GetMissValue**
    ID --> UA : Monitor's value
    UA->ID : **HAL_ICACHE_Monitor_Reset**
    ID --> UA : return HAL_OK
    end
    UA->ID : **HAL_ICACHE_Disable**
    ID --> UA : return HAL_OK
    end
    UA->ID : **HAL_ICACHE_DeInit**
    ID --> UA

    @enduml

Code snippet

HAL1

HAL2

/* Configure ICACHE (optional) */
HAL_ICACHE_ConfigAssociativityMode(ICACHE_1WAY);

/* Enable monitors (optional) */
HAL_ICACHE_Monitor_Start();

/* Enable ICACHE */
HAL_ICACHE_Enable();

/* Maintenance operation (polling) */
if (HAL_ICACHE_Invalidate() != HAL_OK)
{
  Error_Handler();
}

/* Read/Reset monitors (optional) */
(void)HAL_ICACHE_Monitor_GetHitValue();
(void)HAL_ICACHE_Monitor_GetMissValue();
HAL_ICACHE_Monitor_Reset();

/* Stop ICACHE */
HAL_ICACHE_Disable();
HAL_ICACHE_DeInit();
hal_icache_handle_t hicache1;

/* Init triggers a HW invalidate */
if (HAL_ICACHE_Init(&hicache1, HAL_ICACHE1) != HAL_OK)
{
  Error_Handler();
}

/* Optional configuration */
(void)HAL_ICACHE_SetAssociativityMode(&hicache1, HAL_ICACHE_ASSOCIATIVITY_1WAY);
(void)HAL_ICACHE_EnableMonitors(&hicache1);

/* Start ICACHE */
if (HAL_ICACHE_Start(&hicache1, HAL_ICACHE_IT_NONE) != HAL_OK)
{
  Error_Handler();
}

/* Maintenance operation (polling) */
if (HAL_ICACHE_Invalidate(&hicache1) != HAL_OK)
{
  Error_Handler();
}

/* Optional monitors */
(void)HAL_ICACHE_GetMonitorHitValue(&hicache1);
(void)HAL_ICACHE_GetMonitorMissValue(&hicache1);
(void)HAL_ICACHE_ResetMonitors(&hicache1);

/* Stop ICACHE */
(void)HAL_ICACHE_Stop(&hicache1);
(void)HAL_ICACHE_DeInit(&hicache1);

Key changes

  1. HAL2 uses an explicit handle-based init/start/stop flow (HAL_ICACHE_Init(), HAL_ICACHE_Start(), HAL_ICACHE_Stop()), replacing the HAL1 enable/disable approach.

  2. Monitor and configuration APIs are renamed and handle-based in HAL2 (HAL_ICACHE_EnableMonitors(), HAL_ICACHE_GetMonitor*(), HAL_ICACHE_ResetMonitors()).

  3. HAL2 may automatically invalidate the cache during initialization (hardware invalidate on HAL_ICACHE_Init()).


Use case: ICACHE remap region successful

This use case shows how to configure and enable a remapping region using ICACHE, comparing HAL1 and HAL2.

Sequence diagram

    @startuml
    "User\nApplication"->"ICACHE\nDriver": HAL_ICACHE_Disable
    "ICACHE\nDriver"-->"User\nApplication":HAL_OK
    "User\nApplication"->"ICACHE\nDriver": HAL_ICACHE_ConfigAssociativityMode
    "ICACHE\nDriver"-->"User\nApplication":HAL_OK
    note left: return\nstatus
    "User\nApplication"->"ICACHE\nDriver": HAL_ICACHE_EnableRemapRegion
    "ICACHE\nDriver"-->"User\nApplication":HAL_OK
    note left: return\nstatus
    "User\nApplication"->"ICACHE\nDriver": HAL_ICACHE_Enable
    "ICACHE\nDriver"-->"User\nApplication":HAL_OK
    note left: return\nstatus
    @enduml

Code snippet

HAL1

HAL2

HAL_ICACHE_Disable();

HAL_ICACHE_ConfigAssociativityMode(ICACHE_1WAY);

/* Remap SRAM memory */
region_config.TrafficRoute    = ICACHE_MASTER2_PORT;
region_config.OutputBurstType = ICACHE_OUTPUT_BURST_INCR;
region_config.Size            = ICACHE_REGIONSIZE_2MB;
region_config.BaseAddress     = 0x10000000;
region_config.RemapAddress    = 0x60000000;

/* Enable the remapped region */
if (HAL_ICACHE_EnableRemapRegion(ICACHE_REGION_1, &region_config) != HAL_OK)
{
  Error_Handler();
}

/* Enable the Instruction and Data Cache */
HAL_ICACHE_Enable();
HAL_ICACHE_Init(&hicache1, HAL_ICACHE1);

HAL_ICACHE_SetAssociativityMode(&hicache1, HAL_ICACHE_ASSOCIATIVITY_1WAY);

/* Remap SRAM memory */
region_config.master_port   = HAL_ICACHE_MASTER2_PORT;
region_config.output_burst  = HAL_ICACHE_BURST_INCR;
region_config.size          = HAL_ICACHE_REGION_SIZE_2MBYTES;
region_config.base_address  = 0x10000000;
region_config.remap_address = 0x60000000;

/* Configure the remapped region */
if (HAL_ICACHE_SetConfigRemapRegion(&hicache1, HAL_ICACHE_REGION_1, &region_config) != HAL_OK)
{
  Error_Handler();
}

if (HAL_ICACHE_EnableRemapRegion(&hicache1, HAL_ICACHE_REGION_1) != HAL_OK)
{
  Error_Handler();
}

/* Start the Instruction Cache */
HAL_ICACHE_Start(&hicache1, HAL_ICACHE_IT_NONE);

Key changes

  1. HAL2 introduces an explicit configuration step for remap regions (HAL_ICACHE_SetConfigRemapRegion()), separate from enabling the region.

  2. HAL2 uses a handle-based flow (HAL_ICACHE_Init() + HAL_ICACHE_Start()), whereas HAL1 uses global enable/disable APIs.

  3. Several enums/fields are renamed in HAL2 (for example, region size and master port names).

Use case: ICACHE maintenance operations in interrupt mode

This use case shows how to run an ICACHE invalidate operation in interrupt mode, comparing HAL1 and HAL2.

Sequence diagram

    @startuml
    participant "User\nApplication" order 1
    participant "ICACHE\nDriver" order 2
    participant "ICACHE_IRQHandler" order 3
    "User\nApplication"->"ICACHE\nDriver": HAL_ICACHE_Enable
    "ICACHE\nDriver"-->"User\nApplication":HAL_OK
    note left: return\nstatus
    "User\nApplication"->"ICACHE\nDriver": HAL_ICACHE_Invalidate_IT
    note right: Invalid ICACHE interruption enabled\nthen ICACHE disabled
    "ICACHE\nDriver"-->"User\nApplication":HAL_OK or HAL_ERROR
    note left: return\nstatus
    == Interruption Service Routine ==
    "ICACHE_IRQHandler" <-]:Invalidate\ninterrupt
    "ICACHE_IRQHandler" -> "ICACHE\nDriver" : HAL_ICACHE_IRQHandler
    note left: Interruption execution
    "ICACHE\nDriver"->"User\nApplication":HAL_ICACHE_InvalidateCompleteCallback
    @enduml

Code snippet

HAL1

HAL2

/* Enable ICACHE */
HAL_ICACHE_Enable();

/* Start invalidate in interrupt mode */
if (HAL_ICACHE_Invalidate_IT() != HAL_OK)
{
  Error_Handler();
}

/* In ICACHE_IRQHandler(): */
/* HAL_ICACHE_IRQHandler(); */

/* Completion notification */
/* void HAL_ICACHE_InvalidateCompleteCallback(void) { ... } */
/* Optional: register callback */
(void)HAL_ICACHE_RegisterInvalidateCompleteCallback(&hicache1, myICACHE_InvalidateCompleteCallback);

/* Start ICACHE */
if (HAL_ICACHE_Start(&hicache1, HAL_ICACHE_IT_NONE) != HAL_OK)
{
  Error_Handler();
}

/* Start invalidate in interrupt mode */
if (HAL_ICACHE_Invalidate_IT(&hicache1) != HAL_OK)
{
  Error_Handler();
}

/* In ICACHE_IRQHandler(): */
/* HAL_ICACHE_IRQHandler(&hicache1); */

Key changes

  1. HAL2 uses handle-based APIs and a start step (HAL_ICACHE_Start()), while HAL1 uses HAL_ICACHE_Enable().

  2. HAL2 supports callback registration (when USE_HAL_ICACHE_REGISTER_CALLBACKS is enabled) for invalidate-complete notification.

  3. HAL2 keeps the same high-level interrupt flow (request invalidate, then handle in IRQ), but with updated signatures and naming.


Use case: ICACHE error interrupt

This use case shows how ICACHE reports errors via interrupt and callback, comparing HAL1 and HAL2.

Sequence diagram

    @startuml
    participant "User\nApplication" order 1
    participant "ICACHE\nDriver" order 2
    participant "ICACHE_IRQHandler" order 3
    "User\nApplication"->"ICACHE\nDriver": HAL_ICACHE_Enable
    note right: with Error IT enabled
    "ICACHE\nDriver"-->"User\nApplication":HAL_OK
    note left: return\nstatus
    == Interruption Service Routine ==
    "ICACHE_IRQHandler" <-]:Error interrupt
    "ICACHE_IRQHandler" -> "ICACHE\nDriver": HAL_ICACHE_IRQHandler
    note left: Interruption execution
    "ICACHE\nDriver"->"User\nApplication":HAL_ICACHE_ErrorCallback()
    @enduml

Code snippet

HAL1

HAL2

/* Enable ICACHE and its error interrupt (device-specific setup may apply) */
HAL_ICACHE_Enable();

/* In ICACHE_IRQHandler(): */
/* HAL_ICACHE_IRQHandler(); */

/* Error notification */
/* void HAL_ICACHE_ErrorCallback(void) { ... } */
/* Optional: register callback */
(void)HAL_ICACHE_RegisterErrorCallback(&hicache1, ICACHE_Error_UserCallback);

/* Start ICACHE with error interrupt enabled */
if (HAL_ICACHE_Start(&hicache1, HAL_ICACHE_IT_ERROR) != HAL_OK)
{
  Error_Handler();
}

/* In ICACHE_IRQHandler(): */
/* HAL_ICACHE_IRQHandler(&hicache1); */

Key changes

  1. HAL2 exposes error interrupt enable via HAL_ICACHE_Start(..., HAL_ICACHE_IT_ERROR) instead of separate macro-based interrupt enabling.

  2. HAL2 supports callback registration (HAL_ICACHE_RegisterErrorCallback()) when enabled at compile time.

  3. The IRQ flow remains: the ICACHE ISR calls HAL_ICACHE_IRQHandler(), which then dispatches to the user callback.


Use case: ICACHE polling invalidate with error interrupt enabled

This use case shows how to run a polling invalidate operation while the ICACHE error interrupt is enabled, comparing HAL1 and HAL2.

Sequence diagram

    @startuml
    participant "User\nApplication" order 1
    participant "ICACHE\nDriver" order 2
    participant "ICACHE\nIRQHandler" order 3

    skinparam sequenceMessageAlign center

    group Option Register Error Callback
    "User\nApplication" ->"ICACHE\nDriver": HAL_ICACHE_RegisterErrorCallback(USER_ICACHE_ErrorCallback)
    "ICACHE\nDriver"-->"User\nApplication":HAL_OK
    end
    "User\nApplication"->"ICACHE\nDriver": HAL_ICACHE_Enable
    "User\nApplication"->"ICACHE\nDriver": __HAL_ICACHE_ENABLE_IT
    note right: ICACHE_IT_ERROR
    "ICACHE\nDriver"-->"User\nApplication":HAL_OK
    "User\nApplication" [#blue]->"ICACHE\nDriver": HAL_ICACHE_Invalidate
    activate "ICACHE\nDriver" #blue
    note over "ICACHE\nDriver":Check Busy flag : Flag = 0
    "ICACHE\nIRQHandler" <[#orange]-:ICACHE Error interrupt
    "ICACHE\nIRQHandler" -[#orange]> "ICACHE\nDriver" : HAL_ICACHE_IRQHandler
    activate "ICACHE\nDriver" #orange
    note over "ICACHE\nDriver":Flag Error Interrupt = 1

    "ICACHE\nDriver"-[#orange]>"User\nApplication":USER_ICACHE_ErrorCallback(HAL_ICACHE_ERROR_WRITE_INTRUSION)
    "User\nApplication" -[#orange]->"ICACHE\nDriver"

    deactivate "ICACHE\nDriver"
    "ICACHE\nDriver"-[#blue]->"User\nApplication":HAL_OK
    deactivate "ICACHE\nDriver"

    note over "User\nApplication":For other user application
    @enduml

Code snippet

HAL1

HAL2

/* Optional: register error callback */
(void)HAL_ICACHE_RegisterErrorCallback(USER_ICACHE_ErrorCallback);

/* Enable ICACHE and enable error interrupt */
HAL_ICACHE_Enable();
__HAL_ICACHE_ENABLE_IT(ICACHE_IT_ERROR);

/* Polling invalidate */
if (HAL_ICACHE_Invalidate() != HAL_OK)
{
  Error_Handler();
}

/* In ICACHE_IRQHandler(): */
/* HAL_ICACHE_IRQHandler(); */
/* Optional: register error callback */
(void)HAL_ICACHE_RegisterErrorCallback(&hicache1, myICACHE_ErrorCallback);

/* Start ICACHE with error interrupt enabled */
if (HAL_ICACHE_Start(&hicache1, HAL_ICACHE_IT_ERROR) != HAL_OK)
{
  Error_Handler();
}

/* Polling invalidate */
if (HAL_ICACHE_Invalidate(&hicache1) != HAL_OK)
{
  Error_Handler();
}

/* In ICACHE_IRQHandler(): */
/* HAL_ICACHE_IRQHandler(&hicache1); */

Key changes

  1. HAL2 enables error interrupt as part of the HAL_ICACHE_Start() configuration, instead of using __HAL_ICACHE_ENABLE_IT().

  2. HAL2 keeps the invalidate API but updates it to a handle-based signature.

  3. HAL2 supports optional callback registration (HAL_ICACHE_RegisterErrorCallback()) when enabled at compile time.